﻿using System;
using System.Runtime.InteropServices;

namespace ExcelRefresh.Com
{
    // From http://msdn.microsoft.com/en-us/library/ms228772.aspx
    /// <summary>
    /// Handles inter-process thread contention problems
    /// </summary>
    public class OleMessageFilter : IOleMessageFilter, IDisposable
    {
        // Class containing the IOleMessageFilter
        // thread error-handling functions.
        readonly IOleMessageFilter _oldFilter;

        public OleMessageFilter()
        {
            CoRegisterMessageFilter(this , out _oldFilter);
        }

        public void Dispose()
        {
            IOleMessageFilter garbage;
            CoRegisterMessageFilter(_oldFilter, out garbage);
        }

        // IOleMessageFilter functions.
        // Handle incoming thread requests.
        int IOleMessageFilter.HandleInComingCall(
            int dwCallType,
            IntPtr hTaskCaller,
            int dwTickCount,
            IntPtr lpInterfaceInfo)
        {
            //Return the flag SERVERCALL_ISHANDLED.
            return 0;
        }

        // Thread call was rejected, so try again.
        int IOleMessageFilter.RetryRejectedCall(
            IntPtr hTaskCallee,
            int dwTickCount,
            int dwRejectType)
        {
            if (dwRejectType == 2)
            // flag = SERVERCALL_RETRYLATER.
            {
                // Retry the thread call immediately if return >=0 & 
                // <100.
                return 99;
            }
            // Too busy; cancel call.
            return -1;
        }

        int IOleMessageFilter.MessagePending    (
            IntPtr hTaskCallee,
            int dwTickCount,
            int dwPendingType)
        {
            //Return the flag PENDINGMSG_WAITDEFPROCESS.
            return 2;
        }

        // Implement the IOleMessageFilter interface.
        [DllImport("Ole32.dll")]
        private static extern int CoRegisterMessageFilter(
            IOleMessageFilter newFilter,
            out IOleMessageFilter oldFilter);


    }

    //public class MessageFilter : IOleMessageFilter
    //{
    //    // Class containing the IOleMessageFilter
    //    // thread error-handling functions.

    //    // Start the filter.
    //    public static void Register()
    //    {
    //        IOleMessageFilter newFilter = new MessageFilter();
    //        IOleMessageFilter oldFilter = null;
    //        CoRegisterMessageFilter(newFilter, out oldFilter);
    //    }

    //    // Done with the filter, close it.
    //    public static void Revoke()
    //    {
    //        IOleMessageFilter oldFilter = null;
    //        CoRegisterMessageFilter(null, out oldFilter);
    //    }

    //    //
    //    // IOleMessageFilter functions.
    //    // Handle incoming thread requests.
    //    int IOleMessageFilter.HandleInComingCall(
    //        int dwCallType,
    //        System.IntPtr hTaskCaller,
    //        int dwTickCount,
    //        System.IntPtr lpInterfaceInfo)
    //    {
    //        //Return the flag SERVERCALL_ISHANDLED.
    //        return 0;
    //    }

    //    // Thread call was rejected, so try again.
    //    int IOleMessageFilter.RetryRejectedCall(
    //        System.IntPtr hTaskCallee,
    //        int dwTickCount,
    //        int dwRejectType)
    //    {
    //        if (dwRejectType == 2)
    //        // flag = SERVERCALL_RETRYLATER.
    //        {
    //            // Retry the thread call immediately if return >=0 & 
    //            // <100.
    //            return 99;
    //        }
    //        // Too busy; cancel call.
    //        return -1;
    //    }

    //    int IOleMessageFilter.MessagePending(
    //        System.IntPtr hTaskCallee,
    //      int dwTickCount,
    //        int dwPendingType)
    //    {
    //        //Return the flag PENDINGMSG_WAITDEFPROCESS.
    //        return 2;
    //    }

    //    // Implement the IOleMessageFilter interface.
    //    [DllImport("Ole32.dll")]
    //    private static extern int CoRegisterMessageFilter(
    //        IOleMessageFilter newFilter,
    //        out IOleMessageFilter oldFilter);
    //}
}
